#pragma once
#include<iostream>
#include<queue>
#include<pthread.h>

template<class T>
class ThreadPool
{
	private:
		int num;//线程池中有多少个线程
		std::queue<T> q;//给线程池派发任务的地点
		pthread_mutex_t lock;
		pthread_cond_t cond;
	public:
		ThreadPool(int _num):num(_num)
	{
		pthread_mutex_init(&lock,nullptr);
		pthread_cond_init(&cond,nullptr);
	}
		void LockQueue()
		{
			pthread_mutex_lock(&lock);
		}
		void UnlockQueue()
		{
			pthread_mutex_unlock(&lock);
		}
		bool IsEmpty()
		{
			return q.size() == 0;
		}
		void ThreadWait()
		{
			pthread_cond_wait(&cond,&lock);
		}
		void ThreadWakeup()
		{
			pthread_cond_signal(&cond);
		}
		void PopTask(T* out)
		{
                        *out = q.front();
			q.pop();
		}
		void PushTask(const T& in)
		{
			LockQueue();
			q.push(in);
			ThreadWakeup();
			UnlockQueue();
		}
		//Routine是类中的一个成员方法，包含了一个隐式参数this指针
		//但是Routine函数要求只能有一个参数，因此我们需要加上static，消去隐式参数this指针
		static void* Routine(void* args)
		{
			pthread_detach(pthread_self());//线程分离
			ThreadPool* tp = (ThreadPool*)args;

			while(true)
			{
				tp->LockQueue();
				//1、检测是否有任务
				while(tp->IsEmpty())
				{
					tp->ThreadWait();
				}
				//2、取任务
				T t;
				tp->PopTask(&t);
				tp->UnlockQueue();
				//3、处理任务
				t.run();
			}
		}
		void InitThreadPool()
		{
			for(int i = 0; i < num; ++i)
			{
				pthread_t tid;
				pthread_create(&tid,nullptr,Routine,this);
			}
		}
		~ThreadPool()
		{
			pthread_mutex_destroy(&lock);
			pthread_cond_destroy(&cond);
		}
};
